package com.united.ucts.modules.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.united.frame.common.module.service.impl.BaseServiceImpl;
import com.united.ucts.modules.system.mybatis.mapper.RoleMapper;
import com.united.ucts.modules.system.mybatis.mapper.RoleMenuRelationMapper;
import com.united.ucts.modules.system.mybatis.mapper.RoleResourceRelationMapper;
import com.united.ucts.modules.system.pojo.po.*;
import com.united.ucts.modules.system.service.ResourceService;
import com.united.ucts.modules.system.service.RoleService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 后台角色管理业务逻辑接口实现类
 *
 * @author Hudan
 * @version 1.0
 * @filename RoleServiceImpl.java
 * @copyright <a href="www.united.cn">www.united.cn</a>
 * @date 2019-11-23
 */
@Slf4j
@RequiredArgsConstructor
@Component
public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, Role> implements RoleService {

    private final RoleMenuRelationMapper roleMenuRelationMapper;
    private final RoleResourceRelationMapper roleResourceRelationMapper;
    private final ResourceService resourceService;

    /**
     * 添加角色
     *
     * @param role 需要添加的角色信息
     * @return 添加结果
     */
    @Override
    public int create(Role role) {
        role.setCreateTime(LocalDateTime.now());
        role.setAdminCount(0);
        role.setSort(0);
        return baseMapper.insert(role);
    }

    /**
     * 批量删除角色
     *
     * @param ids 需要删除的角色ID集合
     * @return 删除结果
     */
    @Override
    public int delete(List<String> ids) {

        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Role::getId, ids);
        int count = baseMapper.delete(queryWrapper);
        resourceService.initResourceRolesMap();
        return count;
    }

    /**
     * 修改角色信息
     *
     * @param id   需要修改的角色ID
     * @param role 需要修改的角色信息
     * @return 修改结果
     */
    @Override
    public int update(String id, Role role) {
        role.setId(id);
        return baseMapper.updateById(role);
    }

    /**
     * 分页获取角色列表
     *
     * @param pageNum  当前页数
     * @param pageSize 每页大小
     * @param keyword  角色名称关键词
     * @return 分页结果
     */
    @Override
    public List<Role> pageBy(Integer pageNum, Integer pageSize, String keyword) {
        PageHelper.startPage(pageNum, pageSize);

        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(Role::getName, keyword);
        return baseMapper.selectList(queryWrapper);
    }

    /**
     * 获取所有有效角色列表
     *
     * @return 所有有效角色
     */
    @Override
    public List<Role> listAll() {
        return baseMapper.selectList(new QueryWrapper<>());
    }

    /**
     * 根据管理员ID获取对应菜单
     *
     * @param adminId 指定的管理员ID
     * @return 指定管理员的权限菜单
     */
    @Override
    public List<Menu> getMenuList(String adminId) {
        return baseMapper.getMenuList(adminId);
    }

    /**
     * 获取角色相关菜单
     *
     * @param roleId 指定的角色ID
     * @return 指定角色的权限菜单
     */
    @Override
    public List<Menu> listMenu(String roleId) {
        return baseMapper.getMenuListByRoleId(roleId);
    }

    /**
     * 获取角色相关资源
     *
     * @param roleId 指定的角色ID
     * @return 指定角色的权限资源
     */
    @Override
    public List<Resource> listResource(String roleId) {
        return baseMapper.getResourceListByRoleId(roleId);
    }

    /**
     * 给角色分配菜单
     *
     * @param roleId  指定的角色ID
     * @param menuIds 给角色赋予的权限菜单ID集合
     * @return 赋予结果菜单记录条数
     */
    @Override
    public int allocMenu(String roleId, List<String> menuIds) {
        // 先删除原有关系
        LambdaQueryWrapper<RoleMenuRelation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(RoleMenuRelation::getRoleId, roleId);
        roleMenuRelationMapper.delete(queryWrapper);

        // 批量插入新关系
        for (String menuId : menuIds) {
            RoleMenuRelation relation = new RoleMenuRelation();
            relation.setRoleId(roleId);
            relation.setMenuId(menuId);
            roleMenuRelationMapper.insert(relation);
        }
        return menuIds.size();
    }

    /**
     * 给角色分配资源
     *
     * @param roleId      指定的角色ID
     * @param resourceIds 给角色赋予的权限资源ID集合
     * @return 赋予结果资源记录条数
     */
    @Override
    public int allocResource(String roleId, List<String> resourceIds) {
        // 先删除原有关系
        LambdaQueryWrapper<RoleResourceRelation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(RoleResourceRelation::getRoleId, roleId);
        roleResourceRelationMapper.delete(queryWrapper);
        // 批量插入新关系
        for (String resourceId : resourceIds) {
            RoleResourceRelation relation = new RoleResourceRelation();
            relation.setRoleId(roleId);
            relation.setResourceId(resourceId);
            roleResourceRelationMapper.insert(relation);
        }
        resourceService.initResourceRolesMap();
        return resourceIds.size();
    }
}